﻿using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;


using OakEngine.AI.State_Machine;
using OakEngine.AI.Tools;
using OakEngine.BaseObject;

namespace OakEngine.AI.Behavior_State
{
    public class Oak_WanderBehaviorState : Oak_IState<OAK_BaseGameEntity>
    {
        private Vector2 m_vecPosition;
        private const float m_fHysteresis = 15.0f;
        private float m_fSeekMaxDistance;
        private float m_fWanderMaxDistance;
        private float m_fSeekDistanceFromTarget;
        private float m_fTargetDistance;
        private Random random;
        private Vector2 m_vecWanderDirection;

        public void Enter(OAK_BaseGameEntity type)
        {
            m_fSeekMaxDistance = 50.0f;
            m_fWanderMaxDistance = 6.0f;
            m_vecWanderDirection = new Vector2();
            random = new Random();

        }

        public void Execute(OAK_BaseGameEntity type)
        {
            float fWanderSafeDistance = m_fWanderMaxDistance;

            
            // Get the padding for no jitter issues
            fWanderSafeDistance -= m_fHysteresis/2;

            m_fSeekDistanceFromTarget = Vector2.Distance(type.Position, type.TargetPosition);


            // Check if we are close to start seeking
            if (m_fSeekDistanceFromTarget > fWanderSafeDistance)
            {
                //type.ChangeState(new Oak_SeekBehaviorState());
            }
            float rot = type.Rotation;
            Wander(type.Position, ref m_vecWanderDirection, ref type.m_fRotation, type.RotationRate,type.WorldBound);
            type.Rotation = rot;

            float wanderSpeed = 0.25f*type.Speed;

            Vector2 heading = new Vector2((float)Math.Cos(type.Rotation), (float)Math.Sin(type.Rotation));

            type.Velocity = m_vecWanderDirection;
            type.Speed = wanderSpeed;
            type.Rotation = rot;

        }

        private void Wander(Vector2 position, ref Vector2 wanderDirection, ref float rotation, float rotationRate,Rectangle bounds)
        {
            wanderDirection.X += MathHelper.Lerp(-.25f, .25f, (float)random.NextDouble());
            wanderDirection.Y += MathHelper.Lerp(-.25f, .25f, (float)random.NextDouble());

            if(wanderDirection != Vector2.Zero)
                wanderDirection.Normalize();

            rotation = OAK_AITools.TurnToAim(position, position + wanderDirection, rotation, 0.15f*rotationRate);

            // Do some screen protection
            Vector2 screenOrigin = Vector2.Zero;

            screenOrigin.X = bounds.Width*0.5f;
            screenOrigin.Y = bounds.Height*0.5f;

            float distanceFromCenter = Vector2.Distance(screenOrigin, position);
            float maxDistanceFromCenter = Math.Min(screenOrigin.Y, screenOrigin.X);
            float normalizeDistance = distanceFromCenter/maxDistanceFromCenter;
            float turnToCenterSpeed = 0.3f*normalizeDistance*normalizeDistance*rotationRate;

            rotation = OAK_AITools.TurnToAim(position, screenOrigin, rotation, turnToCenterSpeed);

        }

        public void Exit(OAK_BaseGameEntity type)
        {
        }

    }
}
